package com.zwps.common.tool;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollectionUtil;
import lombok.Getter;
import lombok.ToString;

public class DifferenceTool {

//    public static void main(String[] args) {
//        ArrayList<String> news = new ArrayList<String>();
//        news.add("1");
//        news.add("2");
//        news.add("3");
//        ArrayList<String> olds = new ArrayList<String>();
//        olds.add("2");
//        olds.add("4");
//        Comparator<String> comparator = new Comparator<String>() {
//
//            @Override
//            public int compare(String o1, String o2) {
//                return o1.compareTo(o2);
//            }
//        };
//        System.out.println(diff(news, olds, comparator));
//        // print: DifferenceUtil.DifferenceResult(increase=[1, 3], subtract=[4],
//        // unchange=[2])
//    }

    public static <T> DifferenceResult<T> diff(Collection<T> news, Collection<T> olds, Comparator<T> comparator) {
        DifferenceResult<T> result = new DifferenceResult<T>();
        if (olds == null || olds.isEmpty()) {
            if (CollectionUtil.isNotEmpty(news)) {
                result.increase = news instanceof List ? (List<T>) news : news.stream().collect(Collectors.toList());
            }
            return result;
        }
        if (news == null || news.isEmpty()) {
            if (CollectionUtil.isNotEmpty(olds)) {
                result.subtract = olds instanceof List ? (List<T>) olds : olds.stream().collect(Collectors.toList());
            }
            return result;
        }
        for (T o : olds) {
            result.subtract.add(o);
        }
        n: for (T n : news) {
            Iterator<T> subtractIterator = result.subtract.iterator();
            while (subtractIterator.hasNext()) {
                T o = subtractIterator.next();
                if (comparator.compare(n, o) == 0) {
                    result.unchange.add(n);
                    subtractIterator.remove();
                    continue n;
                }
            }
            result.increase.add(n);
        }
        return result;
    }

    @ToString
    @Getter
    public static class DifferenceResult<V> {
        /**
         * 新增的
         */
        private List<V> increase = new ArrayList<V>();
        /**
         * 减少的
         */
        private List<V> subtract = new ArrayList<V>();
        /**
         * 不变的
         */
        private List<V> unchange = new ArrayList<V>();
    }

}
